#include "CtxVisitor.h"
#include "SimpleNode.h"
#include "ast/exprContextType.h"
#include "ast/Name.h"
#include "ast/Starred.h"
#include "ast/Attribute.h"
#include "ast/Subscript.h"
#include "ast/List.h"
#include "ast/Tuple.h"
#include "ast/Call.h"

#include "Object.h"

CtxVisitor::CtxVisitor()
{
}

void CtxVisitor::setParam(const SimpleNodePtr& node)
{
    _ctx = ExprContextType::Param;
    visit(node);
}

void CtxVisitor::setKwOnlyParam(const SimpleNodePtr& node)
{
    _ctx = ExprContextType::KwOnlyParam;
    visit(node);
}

void CtxVisitor::setStore(const SimpleNodePtr& node)
{
    _ctx = ExprContextType::Store;
    visit(node);
}

void CtxVisitor::setStore(const QList<SimpleNodePtr>& nodes)
{
    foreach(SimpleNodePtr node, nodes)
        if (node)
            setStore(node);
}

void CtxVisitor::setDelete(const SimpleNodePtr& node)
{
    _ctx = ExprContextType::Del;
    visit(node);
}

void CtxVisitor::setDelete(const QList<SimpleNodePtr>& nodes)
{
    foreach(SimpleNodePtr node, nodes)
        setDelete(node);
}

void CtxVisitor::setAugStore(const SimpleNodePtr& node)
{
    _ctx = ExprContextType::AugStore;
    visit(node);
}

void CtxVisitor::visitName(const NamePtr& node)
{
    if(_ctx == ExprContextType::Store) {
        if(node->reserved()) {
            throw QString("Cannot assign value to %1 (because it's a keyword)").arg(node->id());
        }
    }
    node->setCtx(_ctx);
}

void CtxVisitor::visitStarred(const StarredPtr& node)
{
    node->setCtx(_ctx);
    traverse(node);
}

void CtxVisitor::visitAttribute(const AttributePtr& node)
{
    node->setCtx(_ctx);
}

void CtxVisitor::visitSubscript(const SubscriptPtr& node)
{
    node->setCtx(_ctx);
}

void CtxVisitor::visitList(const ListPtr& node)
{
    if (_ctx == ExprContextType::AugStore) {
        throw QString("augmented assign to list not possible");
    }
    node->setCtx(_ctx);
    traverse(node);
}

void CtxVisitor::visitTuple(const TuplePtr& node)
{
    if (_ctx == ExprContextType::AugStore) {
        throw QString("augmented assign to tuple not possible");
    }
    node->setCtx(_ctx);
    traverse(node);
}

void CtxVisitor::visitCall(const CallPtr& node)
{
    throw QString("can't assign to function call");
}

void CtxVisitor::visitListComp(const CallPtr& node)
{
    throw QString("can't assign to list comprehension call");
}

void CtxVisitor::unhandled_node(const SimpleNodePtr& node)
{
    throw QString("can't assign to operator:");
}

void CtxVisitor::visitSuite(const SuitePtr& node)
{
    //node->setCtx(_ctx);
    //traverse(node);
}








